package thread.readandwritelock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读写锁 读读可以互通，读写互斥，写写互斥
 *
 * @author ch
 */
public class MyReadAndWriteLock {
    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public static void main(String[] args) {
        final MyReadAndWriteLock myLockInstance = new MyReadAndWriteLock();
        new Thread(new Runnable() {
            @Override
            public void run() {
                myLockInstance.get(Thread.currentThread());
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                myLockInstance.get(Thread.currentThread());
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                myLockInstance.set(Thread.currentThread());
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                myLockInstance.set(Thread.currentThread());
            }
        }).start();



    }

    public void get(Thread thread) {
        lock.readLock().lock();
        try {
            System.out.println("start time:" + System.currentTimeMillis());
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(thread.getName() + ":正在进行读操作……");
            }
            System.out.println(thread.getName() + ":读操作完毕！");
            System.out.println("end time:" + System.currentTimeMillis());
        } finally {
            lock.readLock().unlock();
        }
    }

    public void set(Thread thread) {
        lock.writeLock().lock();
        try {
            System.out.println("start time:" + System.currentTimeMillis());
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(thread.getName() + ":正在进行写操作……");
            }
            System.out.println(thread.getName() + ":写操作完毕！");
            System.out.println("end time:" + System.currentTimeMillis());
        } finally {
            lock.writeLock().unlock();
        }
    }


}

// 这四个方法已经实现
// public acquire
// public release
// public acquireShared
// public releaseShared

// 这四个方法需要自己实现
// protected tryAcquire
// protected tryRelease
// protected tryAcquireShared
// protected tryReleaseShared

// 这四个方法不需要自己实现，aqs已经实现了
// private doAcquire
// private doRelease
// private doAcquireShared
// private doReleaseShared


// 三类方法是这样的调用的
//xxx(){
//    if(tryXxx()){
//        doXxx();
//    }
//}
